package pacBioSimple;

import java.io.BufferedReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Vector;

public class PacBioLinkerObject {

	String fastaName="";
	List<String> fastaSeq = null;
	
	
	public PacBioLinkerObject() {
	}
	
	public PacBioLinkerObject(String fastaName) {
		this.fastaName = fastaName;
	}

	public String getFastaName() {
		return fastaName;
	}

	public void setFastaName(String fastaName) {
		this.fastaName = fastaName;
	}

	public List<String> getFastaSeq() {
		return fastaSeq;
	}

	public void setFastaSeq(List<String> fastaSeq) {
		this.fastaSeq = fastaSeq;
	}
	
	
	
	public void readMultiFasta(List<String> sequences)
	{
		for(int i=0; i < sequences.size();++i)
		{
			StringBuffer sb = new StringBuffer(sequences.get(i));
			maskClipping(sb);
			sequences.set(i, sb.toString());
		}
		this.fastaSeq = sequences;
	}
	
	
	public void readMULTIFasta(BufferedReader process)
	{
		try(BufferedReader brf = process;)
		{
			List<String> fastaSequence = new ArrayList<>();
			StringBuffer sb = new StringBuffer();
			while(brf.ready())
			{
				String line = brf.readLine();
				if(line.charAt(0)=='>')
				{
					if(sb.length()>0)
					{
						maskClipping(sb);
						fastaSequence.add(sb.toString());
						sb = new StringBuffer();
					}
				}
				else
				{
					sb.append(line);
				}
			}
			if(sb.length()>0)
			{
				maskClipping(sb);
				fastaSequence.add(sb.toString());
			}
			this.fastaSeq = fastaSequence;
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	private void maskClipping(StringBuffer sb)
	{
		//slide from the begin and mask every gap with Z until we encounter the first appearance of real nc; 
		int i = 0;
		while(sb.charAt(i) =='-')
		{
			sb.setCharAt(i, 'Z');
			++i;
		}
		//and now from the backside
		
		i = sb.length()-1;
		
		while(sb.charAt(i) =='-')
		{
			sb.setCharAt(i, 'Z');
			--i;
		}
	}
	
	
	public StringBuffer compressToOneSeq()
	{
		try
		{
		StringBuffer sb = new StringBuffer();
		
		for(int i=0; i < this.fastaSeq.get(0).length();++i)
		{
			Vector<Integer> base = new Vector<>();
			
			for(int j=0; j < 5;++j)
			{
				base.add(0);
			}
			
			for(int j=0; j < this.fastaSeq.size();++j)
			{
				switch (this.fastaSeq.get(j).charAt(i)) {
				case 'A':
					base.set(0, base.get(0)+1);
					
					break;
				case 'a':
					base.set(0, base.get(0)+1);
					break;
				case 'C':
					base.set(1, base.get(1)+1);
					break;
				case 'c':
					base.set(1, base.get(1)+1);
					break;
				case 'G':
					base.set(2, base.get(2)+1);
					break;
				case 'g':
					base.set(2, base.get(2)+1);
					break;
				case 'T':
					base.set(3, base.get(3)+1);
					break;
				case 't':
					base.set(3, base.get(3)+1);
					break;
				case '-':
					base.set(4, base.get(4)+1);
					break;
				default:
					break;
				}
			}
			//evaluate if we do nothing or we add
			List<Integer> index = new ArrayList<>();
//			if(base.get(0)+base.get(1)+base.get(2)+base.get(3)>=3)
//			{
//				//here the maximum of the 4 bases is considered
//				int maximum=0;
//				for(int j=0; j < 4;++j)
//				{
//					if(base.get(j) > maximum)
//					{
//						maximum = base.get(j);
//					}
//				}				
//				for(int j=0; j < 4;++j)
//				{
//					if(base.get(j) == maximum)
//					{
//						index.add(j);
//					}
//				}								
//			}
//			else
//			{
				int maximum=0;
				for(int j=0; j < 5;++j)
				{
					if(base.get(j) > maximum)
					{
						maximum = base.get(j);
					}
				}				
				for(int j=0; j < 5;++j)
				{
					if(base.get(j) == maximum)
					{
						index.add(j);
					}
				}
//			}
			
			if(index.size()==1)
			{
				addBase(index.get(0), sb);
			}
			else
			{
				//random selection
				Random random = new Random();
				
				int selected = random.nextInt(index.size());
				addBase(index.get(selected), sb);
			}
			
		}
		return sb;
		}
		catch(Exception e)
		{
			e.printStackTrace();
			for(int i=0; i < this.fastaSeq.size();++i)
			{
				System.out.println(this.fastaSeq.get(i));
			}
			
			System.exit(1);
		}
		return null;
	}
	
	private void addBase(int i , StringBuffer sb)
	{
		switch (i) {
		case 0:
			sb.append("A");
			break;
		case 1:
			sb.append("C");
			break;
		case 2:
			sb.append("G");
			break;
		case 3:
			sb.append("T");
			break;
		default:
			break;
		}
	}
}


